package com.atguigu.srb.core.service.impl;

import com.atguigu.srb.base.util.JwtUtils;
import com.atguigu.srb.common.exception.Assert;
import com.atguigu.srb.common.result.ResponseEnum;
import com.atguigu.srb.core.mapper.IntegralGradeMapper;
import com.atguigu.srb.core.mapper.UserAccountMapper;
import com.atguigu.srb.core.mapper.UserInfoMapper;
import com.atguigu.srb.core.mapper.UserLoginRecordMapper;
import com.atguigu.srb.core.pojo.entity.UserAccount;
import com.atguigu.srb.core.pojo.entity.UserInfo;
import com.atguigu.srb.core.pojo.entity.UserLoginRecord;
import com.atguigu.srb.core.pojo.query.UserInfoQuery;
import com.atguigu.srb.core.pojo.vo.LoginVO;
import com.atguigu.srb.core.pojo.vo.RegisterVO;
import com.atguigu.srb.core.pojo.vo.UserIndexVO;
import com.atguigu.srb.core.pojo.vo.UserInfoVO;
import com.atguigu.srb.core.service.UserInfoService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;

/**
 * <p>
 * 用户基本信息 服务实现类
 * </p>
 *
 * @author lwm
 * @since 2022-02-10
 */
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {
    @Resource
    private UserAccountMapper accountMapper;
    @Resource
    private UserLoginRecordMapper recordMapper;
    @Resource
    private IntegralGradeMapper integralGradeMapper;
    @Resource
    private UserAccountMapper userAccountMapper;
    @Resource
    private UserLoginRecordMapper userLoginRecordMapper;

    //校验手机号是否存在
    @Override
    public Boolean checkMobile(String mobile) {
        LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserInfo::getMobile, mobile);
        Integer count = baseMapper.selectCount(wrapper);
        return count > 0;
    }

    //用户注册
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void register(RegisterVO registerVO) {
        //校验手机号否存在
        Boolean exist = checkMobile(registerVO.getMobile());
        Assert.isTrue(!exist, ResponseEnum.MOBILE_EXIST_ERROR);

        //插入一条用户记录
        UserInfo userInfo = new UserInfo();
        userInfo.setUserType(registerVO.getUserType());
        userInfo.setMobile(registerVO.getMobile());
        userInfo.setNickName(registerVO.getMobile());
        userInfo.setName(registerVO.getMobile());
        userInfo.setPassword(DigestUtils.md5Hex(registerVO.getPassword()));
        userInfo.setHeadImg(UserInfo.DEFAULT_HEAD_IMAGE);
        userInfo.setStatus(UserInfo.STATUS_NORMAL);
        baseMapper.insert(userInfo);

        //插入一条账户记录
        UserAccount userAccount = new UserAccount();
        userAccount.setUserId(userInfo.getId());
        userAccount.setAmount(new BigDecimal("0"));
        userAccount.setFreezeAmount(new BigDecimal("0"));
        accountMapper.insert(userAccount);
    }

    //登录
    @Override
    public UserInfoVO login(LoginVO loginVO, String ip) {
        //是否存在用户
        LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserInfo::getUserType, loginVO.getUserType())
                .eq(UserInfo::getMobile, loginVO.getMobile());
        UserInfo userInfo = baseMapper.selectOne(wrapper);
        Assert.notNull(userInfo, ResponseEnum.LOGIN_MOBILE_ERROR);

        //校验密码
        String inputPassword = DigestUtils.md5Hex(loginVO.getPassword());
        Assert.equals(userInfo.getPassword(), inputPassword, ResponseEnum.LOGIN_PASSWORD_ERROR);

        //是否禁用
        Integer status = userInfo.getStatus();
        Assert.equals(status, UserInfo.STATUS_NORMAL, ResponseEnum.LOGIN_LOKED_ERROR);

        //生成登录记录
        UserLoginRecord userLoginRecord = new UserLoginRecord();
        Long userId = userInfo.getId();
        userLoginRecord.setUserId(userId);
        userLoginRecord.setIp(ip);
        recordMapper.insert(userLoginRecord);

        //生成token
        String token = JwtUtils.createToken(userId, userInfo.getName());
        //封装vo
        UserInfoVO userInfoVO = new UserInfoVO();
        BeanUtils.copyProperties(userInfo, userInfoVO);
        userInfoVO.setToken(token);

        return userInfoVO;
    }

    //获取会员分页列表
    @Override
    public void listPage(Page<UserInfo> page, UserInfoQuery userInfoQuery) {
        LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
        Integer status = userInfoQuery.getStatus();
        Integer userType = userInfoQuery.getUserType();
        String mobile = userInfoQuery.getMobile();
        //动态查询条件
        wrapper.eq(status!=null,UserInfo::getStatus,status)
                .eq(userType!=null, UserInfo::getUserType,userType)
                .eq(StringUtils.hasText(mobile),UserInfo::getMobile,mobile);
        //底层会回填到page模型中，不用返回
        baseMapper.selectPage(page,wrapper);
    }
    //用户锁定和解锁
    @Override
    public void lock(Long id, Integer status) {
        UserInfo userInfo = new UserInfo();
        userInfo.setId(id);
        userInfo.setStatus(status);
        baseMapper.updateById(userInfo);
    }

    //根据用户积分获取可借款额度
    @Override
    public BigDecimal getBorrowAmount(Long userId) {
        BigDecimal borrowAmount = integralGradeMapper.getBorrowAmount(userId);
        if (borrowAmount == null){
            borrowAmount = new BigDecimal("0");
        }
        return borrowAmount;
    }
    //根据协议号拿到用户手机号
    @Override
    public String getMobileByBindCode(String bindCode) {
        QueryWrapper<UserInfo> userInfoQueryWrapper = new QueryWrapper<>();
        userInfoQueryWrapper.eq("bind_code", bindCode);
        UserInfo userInfo = baseMapper.selectOne(userInfoQueryWrapper);
        return userInfo.getMobile();
    }

    //获取用户的个人空间信息
    @Override
    public UserIndexVO getIndexUserInfo(Long userId) {
        //用户信息
        UserInfo userInfo = baseMapper.selectById(userId);

        //账户信息
        QueryWrapper<UserAccount> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",userId);
        UserAccount userAccount = userAccountMapper.selectOne(wrapper);

        //获取最近一次登录日志
        QueryWrapper<UserLoginRecord> userLoginRecordQueryWrapper = new QueryWrapper<>();
        userLoginRecordQueryWrapper
                .eq("user_id",userId)
                .orderByDesc("id")
                .last("limit 1");
        UserLoginRecord userLoginRecord = userLoginRecordMapper.selectOne(userLoginRecordQueryWrapper);


        //组装结果对象
        UserIndexVO userIndexVO = new UserIndexVO();
        userIndexVO.setUserId(userId);
        userIndexVO.setUserType(userInfo.getUserType());
        userIndexVO.setName(userInfo.getName());
        userIndexVO.setNickName(userInfo.getNickName());
        userIndexVO.setHeadImg(userInfo.getHeadImg());
        userIndexVO.setBindStatus(userInfo.getBindStatus());
        userIndexVO.setAmount(userAccount.getAmount());
        userIndexVO.setFreezeAmount(userAccount.getFreezeAmount());
        userIndexVO.setLastLoginTime(userLoginRecord.getCreateTime());

        return userIndexVO;
    }
}
